c <- parsedRemoteConfig remote rc
cst <- remoteCost gc c expensiveRemoteCost
info <- extractS3Info c
- hdl <- mkS3HandleVar c gc u
+ hdl <- mkS3HandleVar False c gc u
magic <- liftIO initMagicMime
return $ new c cst info hdl magic
where
=<< configParser remote c'
c'' <- if isAnonymous pc
then pure c'
- else setRemoteCredPair ss encsetup pc gc (AWS.creds u) mcreds
+ else do
+ v <- setRemoteCredPair ss encsetup pc gc (AWS.creds u) mcreds
+ if M.member datacenterField c || M.member regionField c
+ then return v
+ -- Check if a bucket with this name
+ -- already exists, and if so, use
+ -- that location, rather than the
+ -- default datacenterField.
+ else getBucketLocation pc gc u >>= return . \case
+ Nothing -> v
+ Just loc -> M.insert datacenterField (Proposed $ T.unpack loc) v
pc' <- either giveup return . parseRemoteConfig c''
=<< configParser remote c''
info <- extractS3Info pc'
=<< configParser remote archiveconfig
info <- extractS3Info pc'
checkexportimportsafe pc' info
- hdl <- mkS3HandleVar pc' gc u
+ hdl <- mkS3HandleVar False pc' gc u
withS3HandleOrFail u hdl $
writeUUIDFile pc' u info
use archiveconfig pc' info
where
o = T.pack $ bucketExportLocation info loc
+getBucketLocation :: ParsedRemoteConfig -> RemoteGitConfig -> UUID -> Annex (Maybe S3.LocationConstraint)
+getBucketLocation c gc u = do
+#if MIN_VERSION_aws(0,23,0)
+ info <- extractS3Info c
+ let info' = info { region = Nothing, host = Nothing }
+ -- Force anonymous access, because this API call does not work
+ -- when used in an authenticated context.
+ hdl <- mkS3HandleVar True c gc u
+ withS3HandleOrFail u hdl $ \h -> do
+ r <- liftIO $ tryNonAsync $ runResourceT $
+ sendS3Handle h (S3.getBucketLocation $ bucket info')
+ return $ either (const Nothing) (Just . S3.gblrLocationConstraint) r
+#else
+ return Nothing
+#endif
+
{- Generate the bucket if it does not already exist, including creating the
- UUID file within the bucket.
-
genBucket c gc u = do
showAction "checking bucket"
info <- extractS3Info c
- hdl <- mkS3HandleVar c gc u
+ hdl <- mkS3HandleVar False c gc u
withS3HandleOrFail u hdl $ \h ->
go info h =<< checkUUIDFile c u info h
where
{- Prepares a S3Handle for later use. Does not connect to S3 or do anything
- else expensive. -}
-mkS3HandleVar :: ParsedRemoteConfig -> RemoteGitConfig -> UUID -> Annex S3HandleVar
-mkS3HandleVar c gc u = liftIO $ newTVarIO $ Left $
- if isAnonymous c
+mkS3HandleVar :: Bool -> ParsedRemoteConfig -> RemoteGitConfig -> UUID -> Annex S3HandleVar
+mkS3HandleVar forceanonymous c gc u = liftIO $ newTVarIO $ Left $
+ if forceanonymous || isAnonymous c
then
#if MIN_VERSION_aws(0,23,0)
go =<< liftIO AWS.anonymousCredentials
where
enableversioning b = do
showAction "checking bucket versioning"
- hdl <- mkS3HandleVar c gc u
+ hdl <- mkS3HandleVar False c gc u
let setversioning = S3.putBucketVersioning b S3.VersioningEnabled
withS3HandleOrFail u hdl $ \h ->
#if MIN_VERSION_aws(0,24,3)
embedcreds without gpg encryption.
* `datacenter` - Specifies which Amazon datacenter
- to use for the bucket. Defaults to "US". Other values include "EU"
- (which is EU/Ireland), "us-west-1", "us-west-2", "ap-southeast-1",
- "ap-southeast-2", and "sa-east-1". See Amazon's documentation for a
- complete list. Configuring this is equivilant to configuring both
- `host` and `region`.
+ to use when creating a bucket. Defaults to "US". Other values include "EU"
+ (which is EU/Ireland), "us-west-1", "us-west-2", etc. See Amazon's
+ documentation for a complete list. Configuring this is equivilant to
+ configuring both `host` and `region`.
* `storageclass` - Default is "STANDARD".
Consult S3 provider documentation for pricing details and available